home *** CD-ROM | disk | FTP | other *** search
- /*-------------------------------------------------------------------
-
- AOCE Post Office Protocol (POP) / Simple Mail Transfer Protocol (SMTP)
- Mail Service Access Module
-
- written by Steve Falkenburg-- MacDTS
- ©1991-1993 Apple Computer, Inc.
-
- --------------
- change history
- --------------
-
- SJF 02/19/93 update for beta build b1
- SJF 10/29/92 update to a11 a11
- SJF 06/08/92 update to a8 a8
- SJF 02/15/92 first working version a4.5
- SJF 10/16/91 initial coding a3
-
- ---------------------------------------------------------------------*/
-
- #ifndef __TYPES__
- #include <Types.h>
- #endif
-
- #ifndef __PROCESSES__
- #include <Processes.h>
- #endif
-
- #ifndef __OCE__
- #include <OCE.h>
- #endif
-
- #ifndef __OCEERRORS__
- #include <OCEErrors.h>
- #endif
-
- #include "const.h"
- #include "gwerrors.h"
- #include "mytypes.h"
- #include "globals.h"
- #include "utils.h"
- #include "gatewaystuff.h"
- #include "gatewayget.h"
- #include "gatewayput.h"
-
- #include "gatewayevents.h"
-
-
- // DoGatewayEvent
- //
- // handles high level events passed from the AOCE toolbox to the MSAM
- //
- // input: messageID -- identifies the high level event
- // mailEPPC -- mail EPPC message area containing shared mem area and msg seq number
- // slotID -- slot ID (if used)
- // inMainEventLoop -- true if we're being called from our main event loop
- //
- // on exit, the result field of the SMCA is set to the appropriate error code, indicating
- // that the MSAM is done processing the event
- //
- // note: I removed the EPPC handlers for MailboxOpened, MailboxClosed, and SendImmediate, as
- // they are no longer of value to the MSAM
- //
- // note: only CreateSlot, ModifySlot, DeleteSlot and message opened EPPCs are reliable
- // all others are informational only and may not always be sent (no guarantees)
- //
- // online gateway note: we do not handle kMailEPPCInQUpdate, kMailEPPCMsgOpened
- // since we are not an online gateway
- //
- OSErr DoGatewayEvent(long messageID,MailEPPCMsg *mailEPPC,short slotID,Boolean inMainEventLoop)
- {
- OSErr err;
-
- if (mailEPPC && mailEPPC->version != kMailEPPCMsgVersion) // check version of smca
- return kOCEVersionErr;
-
- err = noErr;
-
- switch (messageID) {
-
- // create a new slot
- case kMailEPPCCreateSlot:
- err = CreateSlot(gMSAMCID,mailEPPC->u.theSMCA->u.slotCID);
- mailEPPC->u.theSMCA->result = err;
- break;
-
- // modify the contents of an existing slot
- case kMailEPPCModifySlot:
- err = ModifySlot(gMSAMCID,GetSlotSpecFromID(slotID),mailEPPC->u.theSMCA->u.slotCID);
- mailEPPC->u.theSMCA->result = err;
- break;
-
- // delete an existing slot
- case kMailEPPCDeleteSlot:
- err = DeleteSlot(gMSAMCID,GetSlotSpecFromID(slotID));
- mailEPPC->u.theSMCA->result = err;
- break;
-
- // shut down the gateway
- case kMailEPPCShutDown:
- err = ShutDownServer();
- break;
-
- // instructs the gateway to continue operation after previously suspending itself
- case kMailEPPCContinue:
- if (slotID==0)
- err = ContinueOperation(nil);
- else
- err = ContinueOperation(GetSlotSpecFromID(slotID));
- break;
-
- // informs a gateway that it's time to wake up (when a mail check timer expires)
- case kMailEPPCSchedule:
- if (inMainEventLoop)
- err = TimeToCheckForMail();
- else {
- err = EnqueueHighLevelEvent(kMailEPPCSchedule,nil,slotID);
- }
- break;
-
- // instructs a gateway to update its incoming queue (for post-its)
- case kMailEPPCInQUpdate:
- mailEPPC->u.theSMCA->result = noErr; // don't handle, since we're not online
- break;
-
- // instructs a gateway that a message was opened (for post-its)
- case kMailEPPCMsgOpened:
- mailEPPC->u.theSMCA->result = noErr; // don't handle, since we're not online
- break;
-
- // instructs a gateway to wake up due to an external event (something bad happened)
- case kMailEPPCWakeup:
- err = WakeupFromExternalEvent();
- break;
-
- // notification that gateway has a letter in outgoing queue
- case kMailEPPCMsgPending:
- if (inMainEventLoop)
- err = MessagePending(GetSlotSpecFromID(slotID));
- else {
- err = EnqueueHighLevelEvent(kMailEPPCMsgPending,nil,slotID);
- }
- break;
-
- case kMailEPPCSendImmediate:
- // should save away sequence number to send now
- // also should force sending now…
- mailEPPC->u.theSMCA->result = noErr; // don't handle, since we're not online
- break;
-
- case kMailEPPCLocationChanged:
- // look at MailLocationInfo
- // we don't support new locations for "i'm at"
- break;
-
- // these aren't handled
- case kMailEPPCMailboxOpened:
- case kMailEPPCMailboxClosed:
- case kMailEPPCDeleteOutQMsg:
- err = noErr;
- break;
-
- // unsupported high level event
- defaut:
- err = kUndefinedHighLevelEvent;
- break;
- }
-
- return err;
- }
-
-
- OSErr EnqueueHighLevelEvent(long messageID,MailEPPCMsg *mailEPPC,short slotID)
- {
- HLEventQ *newEl;
-
- newEl = NewPtrChk(sizeof(HLEventQ));
- if (MemError()!=noErr)
- return MemError();
-
- newEl->messageID = messageID;
- newEl->mailEPPC = mailEPPC;
- newEl->slotID = slotID;
-
- newEl->next = gHLEventAdd;
- newEl->prev = nil;
- gHLEventAdd->prev = newEl;
- gHLEventAdd = newEl;
- if (gHLEventRemove==nil)
- gHLEventRemove = newEl;
-
- return noErr;
- }
-
-
- Boolean DequeueHighLevelEvent(long *messageID,MailEPPCMsg **mailEPPC,short *slotID)
- {
- HLEventQ *oldQ;
-
- if (!gHLEventRemove)
- return false;
-
- *messageID = gHLEventRemove->messageID;
- *mailEPPC = gHLEventRemove->mailEPPC;
- *slotID = gHLEventRemove->slotID;
-
- oldQ = gHLEventRemove;
- gHLEventRemove = gHLEventRemove->prev;
- if (gHLEventRemove)
- gHLEventRemove->next = nil;
- else
- gHLEventAdd = nil;
-
- DisposPtrChk(oldQ);
-
- return true;
- }
-
-
- OSErr ProcessQueuedEvents(void)
- {
- long messageID;
- MailEPPCMsg *mailEPPC;
- short slotID;
- OSErr err;
-
- err = noErr;
- while (DequeueHighLevelEvent(&messageID,&mailEPPC,&slotID) && err==noErr) {
- err = DoGatewayEvent(messageID,mailEPPC,slotID,true);
- }
- return err;
- }
-
-
- // CreateSlot
- //
- // high level call to process the Create Slot high level event
- //
- // inputs: msamCID -- creation ID of the MSAM setup record
- // slotCID -- creation ID of the new slot information
- //
- OSErr CreateSlot(CreationID msamCID,CreationID slotCID)
- {
- #pragma unused (msamCID)
- OSErr err;
- short slotID;
-
- TraceExecution("\pCreateSlot");
-
- // add SlotID to mailservice record
-
- slotID = 1; // we only have 1 slot for now, so it is always ID 1
-
- err = AddAttribute(&slotCID,gAOCESetupDSRef,OCEGetIndAttributeType(kSlotIDAttrTypeNum),
- &slotID,sizeof(short),typeBinary);
- if (err!=noErr)
- return err;
-
- MarkSlotInformationDirty(); // mark that slots need to be updated at main event time
- return noErr;
- }
-
-
- // ModifySlot
- //
- // high level call to process the Modify Slot high level event
- //
- // inputs: msamCID -- creation ID of the MSAM setup record
- // slot -- slot specifier for the slot being modified
- // slotCID -- creation ID of the modified slot information
- //
- OSErr ModifySlot(CreationID msamCID,SlotSpec *slot,CreationID slotCID)
- {
- #pragma unused (msamCID,slot,slotCID)
-
- TraceExecution("\pModifySlot");
-
- MarkSlotInformationDirty(); // mark that slots need to be updated at main event time
- return noErr;
- }
-
-
- // DeleteSlot
- //
- // high level call to process the Delete Slot high level event
- //
- // inputs: msamCID -- creation ID of the MSAM setup record
- // slot -- slot specifier for the slot being deleted
- //
- OSErr DeleteSlot(CreationID msamCID,SlotSpec *slot)
- {
- #pragma unused(msamCID,slot)
-
- TraceExecution("\pDeleteSlot");
- MarkSlotInformationDirty(); // mark that slots need to be updated at main event time
- return noErr;
- }
-
-
- // ShutDownServer
- //
- // high level call to process the ShutDownServer high level event
- // sets gDone to true, indicating that we'll quit the next time through our event loop
- //
- OSErr ShutDownServer(void)
- {
- TraceExecution("\pShutDownServer");
-
- gDone = true;
- return noErr;
- }
-
-
- // MessagePending
- //
- // high level call to process the MessagePending high level event.
- // increments the number of messages pending counter on the slot the message is pending for.
- //
- OSErr MessagePending(SlotSpec *slot)
- {
- OSErr err;
-
- TraceExecution("\pMessagePending");
-
- // if the slot isn't suspended, do the send now
-
- if (slot && slot->enabled)
- err = DoSlotGet(slot);
-
- return err;
- }
-
-
- // ContinueOperation
- //
- // process continue high level event, which instructs a gateway to continue operation after
- // previously suspending itself. it's permissible to have a gateway quit itself between
- // transactions. if this is done, each time the gateway is launched, it will get a
- // continue eppc.
- //
- // input: slot contains the slot specification for the slot being resumed, or nil of
- // the continue applies to the entire gateway.
- //
- OSErr ContinueOperation(SlotSpec *slot)
- {
- TraceExecution("\pContinueOperation");
-
- if (slot)
- slot->enabled = true;
-
- return noErr;
- }
-
-
- // TimeToCheckForMail
- //
- // process schedule high level event, which is sent by the toolbox when the check for mail
- // timers specified in the slot configuration records expire. this event makes it so the
- // gateway doesn't continually have to poll to see if the checking timers have expired
- //
- OSErr TimeToCheckForMail(void)
- {
- OSErr err,err2;
-
- TraceExecution("\pTimeToCheckForMail");
-
- // do gets/puts for slots whose timers have expired
-
- err = PeriodicCheckGet();
- err2 = PeriodicCheckPut();
-
- if (err==noErr)
- err = err2;
-
- return err;
- }
-
-
- // WakeupFromExternalEvent
- //
- // process the wakeup high level event, which instructs a gateway to wake up due to
- // an external event that cannot be predicted by AOCE if a gateway receives an
- // eppcWakeup event just after being launched, it syhould take that to mean that it
- // was launched in response to an external event. if the gateway was al;ready running
- // when the event arrived, it is an indication that ian external event important to the
- // gateway has occured. the wakeup attempt is not reliable
- //
- OSErr WakeupFromExternalEvent(void)
- {
- TraceExecution("\pWakeupFromExternalEvent");
- return noErr;
- }
-